/**
 * 通用工具函数
 */
import CryptoJS from 'crypto-js';

/**
 * 判断是否为空
 */
export function isEmpty(value: any): boolean {
  if (typeof value === "undefined" || value === null || 
      (typeof value === "string" && value.trim() === "") || 
      (Array.isArray(value) && value.length === 0) || 
      (typeof value === "object" && Object.keys(value).length === 0)) {
    return true;
  } else {
    return false;
  }
}

/**
 * 加密
 * @param {string} plainText 明文
 * @returns {string} 密文
 */
export const encrypt = (plainText: string): string => {
  // 使用默认密钥
  const cryptoKey = 'aoligeimeimaobin';
  
  // 加密配置
  let options = {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  };
  
  // 执行加密
  let key = CryptoJS.enc.Utf8.parse(cryptoKey);
  let encryptedData = CryptoJS.AES.encrypt(plainText, key, options);
  
  // 返回加密结果，替换特殊字符
  return encryptedData.toString().replace(/\//g, "_").replace(/\+/g, "-");
};

/**
 * 解密
 * @param {string} encryptedBase64Str 密文
 * @returns {string} 明文
 */
export function decrypt(encryptedBase64Str: string): string {
  // 使用默认密钥
  const cryptoKey = 'aoligeimeimaobin';
  
  // 替换特殊字符
  let val = encryptedBase64Str.replace(/\-/g, '+').replace(/_/g, '/');
  
  // 解密配置
  let options = {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  };
  
  // 执行解密
  let key = CryptoJS.enc.Utf8.parse(cryptoKey);
  let decryptedData = CryptoJS.AES.decrypt(val, key, options);
  
  // 返回解密结果
  return CryptoJS.enc.Utf8.stringify(decryptedData);
}

/**
 * 格式化日期
 * @param {Date|string|number} date 日期对象或时间戳
 * @param {string} fmt 格式化模板，如 yyyy-MM-dd hh:mm:ss
 * @returns {string} 格式化后的日期字符串
 */
export function formatDate(date: Date | string | number, fmt: string = 'yyyy-MM-dd hh:mm:ss'): string {
  if (!date) return '';
  
  const d = new Date(date);
  if (isNaN(d.getTime())) return '';
  
  const o: Record<string, number> = {
    'M+': d.getMonth() + 1,
    'd+': d.getDate(),
    'h+': d.getHours(),
    'm+': d.getMinutes(),
    's+': d.getSeconds(),
    'q+': Math.floor((d.getMonth() + 3) / 3),
    'S': d.getMilliseconds()
  };
  
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  
  for (const k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k] + '') : (('00' + o[k]).substr(('' + o[k]).length)));
    }
  }
  
  return fmt;
}

/**
 * 防抖函数
 * @param {Function} func 要防抖的函数
 * @param {number} wait 等待时间（毫秒）
 * @param {boolean} immediate 是否立即执行
 * @returns {Function} 防抖后的函数
 */
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number = 300,
  immediate: boolean = false
): (...args: Parameters<T>) => void {
  let timeout: ReturnType<typeof setTimeout> | null = null;

  return function (this: any, ...args: Parameters<T>) {
    const context = this;
    const later = () => {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    const callNow = immediate && !timeout;
    
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };
}